package com.log4jviewer.ui.preferences.additional;

import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotCheckBox;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotLabel;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotSpinner;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;

import utils.swtbot.UITest;

/**
 * The class that encapsulates all the necessary tools to simplify "Additional" plugin preferences page writing tests.
 * 
 * @author <a href="mailto:Daniil.Yaroslavtsev@gmail.com">Daniil Yaroslavtsev</a>
 * 
 */
public abstract class AbstractAdditionalPageTest extends UITest {

    /** The UI testing bot. */
    private static SWTWorkbenchBot bot = getBot();

    /** The "Move up" button. */
    private static SWTBotButton moveUpButton;

    /** The "Move Down" button. */
    private static SWTBotButton moveDownButton;

    /** The "Restore defaults" button. */
    private static SWTBotButton restoreDefaultsButton;

    /** The "Apply" button. */
    private static SWTBotButton applyButton;

    /** The "Cancel" button. */
    private static SWTBotButton cancelButton;

    /** The "OK" button. */
    private static SWTBotButton buttonOK;

    /** The logs font size label. */
    private static SWTBotLabel logsFontSizeLabel;

    /** The "use image..." label. */
    private static SWTBotLabel useImageLabel;

    /** The "use image.." check box. */
    private static SWTBotCheckBox useImageCheckBox;

    /** The logs font size spinner. */
    private static SWTBotSpinner logsFontSizeSpinner;

    /** The log table. */
    private static SWTBotTable logTable;

    /** The log display table. */
    private static SWTBotTable logDisplayTable;

    @BeforeClass
    public static void beforeClass() {
        setupSWTBotParams();
        // BOT.resetWorkbench();  // set the workbench to it`s initial state

        closeUnnecessaryViewsIfNeeded();

        openAdditionalPreferencesPage(); // Open the "Additional" page           
        findAndParsePageControls(); // and parse it`s controls.  
    }

    @Before
    public void beforeTest() {
        setInitialPageState();
    }

    @After
    public void afterTest() {
        // no code
    }

    @AfterClass
    public static void afterClass() {
        closePreferencesDialog();
        doSleepBetweenTests();
    }

    /**
     * Opens the "Additional" preferences page.
     */
    protected static void openAdditionalPreferencesPage() {
        bot.menu("Window").menu("Preferences").click();

        SWTBotTree tree = bot.tree();

        SWTBotTreeItem item = tree.getTreeItem("Log4j-Viewer");
        item.doubleClick(); // click "Log4j-Viewer"

        // Filters menu item
        SWTBotTreeItem additionalItem = item.getNode("Additional");
        additionalItem.doubleClick(); // click "Additional"
    }

    /**
     * Finds and parses all controls on "Additional" preferences page.
     * 
     */
    protected static void findAndParsePageControls() {
        moveUpButton = bot.buttonInGroup("MoveUp", "Log Table columns");
        moveDownButton = bot.buttonInGroup("MoveDown", "Log Table columns");

        logTable = bot.tableInGroup("Log Table columns");
        logDisplayTable = bot.tableInGroup("Log display");

        useImageLabel = bot.labelInGroup("Use level image in the Level column", "Log display");
        useImageCheckBox = bot.checkBoxInGroup("Log display");

        logsFontSizeLabel = bot.labelInGroup("Log's font size", "Log display");
        logsFontSizeSpinner = bot.spinnerInGroup("Log display");

        restoreDefaultsButton = bot.button("Restore Defaults");
        applyButton = bot.button("Apply");
        cancelButton = bot.button("Cancel");
        buttonOK = bot.button("OK");
    }

    // Setters 

    /**
     * Sets the "font size" spinner selection.
     * 
     * @param value
     *            - new spinner selection (new font size).
     */
    protected static void setFontSizeSpinnerSelection(final int value) {
        logsFontSizeSpinner.setSelection(value);
    }

    // Getters 

    /**
     * Gets the Log Table.
     * 
     * @return the Log Table.
     */
    public static SWTBotTable getLogTable() {
        return logTable;
    }

    /**
     * Gets the Log Display Table.
     * 
     * @return the Log Display Table.
     */
    public static SWTBotTable getLogDisplayTable() {
        return logDisplayTable;
    }

    /**
     * Gets the spinner selection.
     * 
     * @return The spinner selection.
     */
    protected static int getFontSizeSpinnerSelection() {
        return logsFontSizeSpinner.getSelection();
    }

    // "press ... button" methods

    /**
     * Presses the "Move Down" button.
     */
    protected void pressMoveDownButton() {
        moveDownButton.click();
    }

    /**
     * Presses the "Move Up" button.
     */
    protected void pressMoveUpButton() {
        moveUpButton.click();
    }

    /**
     * Presses the "Restore Defaults" button.
     */
    protected void pressRestoreDefaultsButton() {
        restoreDefaultsButton.click();
    }

    /**
     * Presses an "Apply" button.
     * */
    protected static void pressApplyButton() {
        applyButton.click(); // apply changes
    }

    /**
     * Presses an "OK" button.
     * */
    protected static void pressOkButton() {
        buttonOK.click(); // apply changes
    }

    /**
     * Presses the "Cancel" button.
     * */
    protected static void pressCancelButton() {
        cancelButton.click(); // apply changes
    }

    /**
     * Closes the preferences dialog without saving changes.
     */
    protected static void closePreferencesDialog() {
        pressCancelButton();
    }

    /**
     * Sets all "Additional" preferences page controls to their initial state.
     * */
    protected void setInitialPageState() {
        if (!useImageCheckBox.isChecked()) {
            useImageCheckBox.click();
        }
        logsFontSizeSpinner.setSelection(11);
        pressApplyButton();
    }

}
